home *** CD-ROM | disk | FTP | other *** search
- /*fast broadcast icmp chech macro*/
-
- call init
- call cycle
- exit
- /***************************************************************************/
- err: procedure expose global.
- parse arg msg,ntsockerr,ntprg
- if ntsockerr~=1 then msg=msg "("errorstring(errno())")"
- if ntprg~=1 then msg=global.prg":" msg
- call writeln(global.stderr,msg)
- exit
- /***************************************************************************/
- info: procedure expose global.
- parse arg msg
- call writeln(global.stderr,msg)
- return
- /***************************************************************************/
- getsuitable: procedure expose global.
- res=QueryInterfaces("IN")
- if res>0 then
- do i=0 to res-1
- if in.i.family==2 & in.i.UP==1 & in.i.LOOPBACK==0 then return in.i.IFADDRS
- end
- return -1
- /***************************************************************************/
- init: procedure expose global.
- if ~open("GLOBAL.STDERR","CONSOLE:","W") then global.stderr="STDOUT"
- l="rmh.library";if ~show("L",l) then;if ~addlib(l,0,-30) then call err "can't find rmh.library any version",1,1
- global.prg=programName("NOEXT")
- if AddLibrary("rexxsupport.library","rxsocket.library","rxlibnet.library")~=0 then err "can't find" result
- parm.1.value=3
- if ~RMH_ReadArgs("FILE/A,TIMEOUT/N,VER=VERBOSE/S,MIN/K/N") then do
- call printfault(ioerr(),global.prg)
- exit
- end
- global.myAddr=getSuitable()
- if global.myAddr=-1 then call err "no suitable device found",1
- global.file=parm.0.value
- global.timeout=parm.1.value
- if global.timeout<0 then call err "bad timeout value '"global.timeout"'",1
- global.ver=parm.2.flag
- if parm.3.flag then
- if parm.3.value<0 then err "bad min value '"parm.3.value"'",1
- else global.minRet=parm.3.value
- else global.minRet=0
- if ~open("IN",global.file,"R") then call err "file '"global.file"' not found",1
- global.sock=socket("INET","RAW","ICMP")
- if global.sock<0 then call err "socket not created"
- call setsockopt(global.sock,"SOCKET","BROADCAST",1)
- call setsockopt(global.sock,"IP","HDRINCL",1)
- call IOCtlSocket(global.sock,"FIONBIO",1)
- global.tim=CreateTimer()
- global.ts=TimerSignal(global.tim)
- global.id=x2d(right(pragma("ID"),4))
- global.ip.v = 4
- global.ip.hl = 5
- global.ip.tos = 0
- global.ip.id = global.id
- global.ip.off = 0
- global.ip.ttl = 65
- global.ip.p = 1
- global.ip.src = global.myAddr
- global.null=Null()
- global.icmp.type=8
- global.icmp.code=0
- global.icmp.id=global.id
- global.icmp.seq=0
- global.sel.read.0=global.sock
- global.sig=or(global.ts,2**12)
- if global.ver then call info "File:"global.file "Timeout:"global.timeout "Addr:"global.myAddr
- return
- /***************************************************************************/
- cycle: procedure expose global.
- i=0
- do while ~eof("IN")
- w=-1
- do k=0 to 19
- drop global.ips
- line=readln("IN")
- if line~="" then do
- parse var line broad .
- parse var line broad "9"x
- broad=space(broad)
- i=i+1
- if isDotAddr(broad) then do
- w=w+1
- global.ips.w.name=broad
- global.ips.w.count=0
- call sendEchoReq(broad,w)
- end
- else say ";" left(broad,15) "*** bad dotted ***"
- end
- end
- if w>=0 then do
- call waitEcho(broad)
- do k=0 to w
- if global.ips.k.count>=global.minRet then say "BROADCAST" left(global.ips.k.name,15) ";" global.ips.k.count
- end
- end
- end
- return
- /***************************************************************************/
- sendEchoReq: procedure expose global.
- parse arg broad,i
- remote.addraddr=broad
- global.ip.dst = broad
- call GetSysTime("T")
- global.icmp.icmpdata=right(global.null||d2c(t.secs),4) right(global.null||d2c(t.micro),4)
- global.icmp.seq=i
- icmpPkt=createicmp("GLOBAL.ICMP")
- global.ip.len = 20+length(icmpPkt)
- ipPkt=createip("GLOBAL.IP")
- if global.ver then call info "sending eco request to <"broad"> ["i"]"
- p=ipPkt||icmpPkt
- global.plen=length(p)
- if sendto(global.sock,p,0,"REMOTE")<0 then call err "error sending"
- return
- /***************************************************************************/
- waitecho: procedure expose global.
- if global.ver then call info " .waiting for eco reply"
- do while 1
- res=WaitSelect("GLOBAL.SEL",,,global.sig)
- if and(global.sel.signals,2**12)~=0 then call err "user break",1
- if res<0 then call err "error waitselect"
- if res=0 then do
- if global.timeout>0 then call StopTimer(global.tim)
- return
- end
- if global.timeout>0 then call StartTimer(global.tim,global.timeout)
- res=recvfrom(global.sock,"PKT",global.plen)
- if res<0 then call "error recv"
- parse var pkt ipPkt +20 t +1 c +1 ck +2 i +2 seq +2
- if c2d(t)=0 & c2d(i)=global.id then do
- s=c2d(seq)
- global.ips.s.count=global.ips.s.count+1
- end
- end
- /* not reached */
- /***************************************************************************/
-